/*
    This file is part of Epoch <http://code.google.com/p/epoch/>.
    
    Copyright (C) 2011  Adam Meily <meily.adam@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include "Message.h"
#include <QDateTime>

Message::Message()// : m_recordIndex(-1) // m_mode(HeaderOnly)
{
    
}

Message::Message(const Message& other) : //m_mode(other.m_mode),
                                         m_args(other.m_args),
                                         m_operation(other.m_operation),
                                         //m_recordIndex(other.m_recordIndex),
                                         m_records(other.m_records)
{

}

Message::Message(const QStringList& input) //:m_recordIndex(-1) // m_mode(HeaderOnly)
{
    if(input.length() == 0)
        return;
    
    int len = input.length();
    // get op
    QString raw = prepareInput(input[0]);
    int index = raw.indexOf(' ');
    if(index < 0)
        m_operation = raw.toLower();
    else
    {
        m_operation = raw.left(index).toLower();
        m_args = parseRecord(raw.right(raw.length() - index));
        
        //if(m_args.contains("mode"))
        //    m_mode = parseMode(m_args.take("mode").toLower());
    }
    
    for(int i = 1; i < len; i++)
    {
        Record r = parseRecord(input[i]);
        if(!r.isEmpty())
            m_records.append(r);
    }
}

Message& Message::operator=(const Message& other)
{
    m_args = other.m_args;
    //m_mode = other.m_mode;
    m_operation = other.m_operation;
    //m_recordIndex = other.m_recordIndex;
    m_records = other.m_records;
    return *this;
}


Message::~Message()
{

}

QString Message::prepareInput(const QString& input) const
{
    return input.trimmed().replace('\t', ' ');
}

Record Message::parseRecord(const QString& input) const
{
    Record r;
    int pos = -1;
    QRegExp re("([\\w\\-]+)=\"((?:[^\"\\\\]|\\\\.)*)\"");
    while((pos = re.indexIn(input, pos)) != -1)
    {
        QString opt = re.cap(1).toLower();
        QString val = re.cap(2);
        r.insert(opt, val);
        pos += re.matchedLength();
    }
    
    return r;
}

/*
Message::Mode Message::parseMode(const QString& input) const
{
    Mode m = HeaderOnly;
    if(input == "single-record")
        m = SingleRecord;
    else if(input == "multi-records")
        m = MultiRecords;
    else if(input == "binary")
        m = BinaryData;
    
    return m;
}
*/

const Record& Message::args() const
{
    return m_args;
}

void Message::args(const Record& args)
{
    m_args = args;
}

Record& Message::args()
{
    return m_args;
}

void Message::addArg(const QString& key, const QString& value)
{
    m_args.insert(key, value);
}


void Message::addRecord(const Record& record)
{
    m_records.append(record);
}

/*
bool Message::hasNextRecord() const
{
    return (m_recordIndex + 1) < m_records.length();
}

int Message::nextRecord()
{
    if(hasNextRecord())
        m_recordIndex++;
    
    return m_recordIndex;
}

int Message::recordCount() const
{
    return m_records.length();
}
*/

const QList< Record >& Message::records() const
{
    return m_records;
}

QListIterator< Record > Message::recordIterator() const
{
    return QListIterator<Record>(m_records);
}


/*
const QString& Message::id() const
{
    return m_id;
}

void Message::id(const QString& id)
{
    m_id = id;
}

void Message::genid()
{
    QDateTime d(QDateTime::currentDateTime());
    qint64 ts = d.toMSecsSinceEpoch();
    int r = qrand();
    
    QByteArray out;
    out.append(QByteArray::number(ts, 10));
    out.append(QByteArray::number(r, 10));
    m_id = out.toHex();
}
*/

/*
Message::Mode Message::mode() const
{
    return m_mode;
}

void Message::mode(Message::Mode mode)
{
    m_mode = mode;
    
}
*/
const QString& Message::operation() const
{
    return m_operation;
}

void Message::operation(const QString& op)
{
    m_operation = op;
}

/*
const Record& Message::record() const
{
    if(m_recordIndex >= 0)
        return m_records[m_recordIndex];
    return NullRecord;
}

Record& Message::record()
{
    if(m_recordIndex >= 0)
        return m_records[m_recordIndex];
    return NullRecord;
}
*/

/*
void Message::setMode()
{
    if(m_mode == SingleRecord)
        m_args["mode"] = "single-record";
    else if(m_mode == MultiRecords)
        m_args["mode"] = "multi-records";
    else if(m_mode == BinaryData)
        m_args["mode"] = "binary-data";
}
*/
